﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Management;
using System.Runtime.InteropServices;
using System.Text;

namespace Shared.Method
{
    public class ArpBaseClass
    {
        [DllImport("Iphlpapi.dll")]
        private static extern int SendARP(int dest, int source, ref long mac, ref int length);//发送ARP包
        [DllImport("Ws2_32.dll")]
        private static extern int inet_addr(string ip);

        /// <summary>
        /// 获得指定IP的MAC地址
        /// </summary>
        /// <param name="sourceIp">源IP</param>
        /// <param name="destIp">目的IP</param>
        /// <returns>MAC地址</returns>
        public static string GetMacFromIp(string sourceIpStr, string destIpStr)
        {
            try
            {
                if (IsIpEnabled(sourceIpStr) == false) return null;//IP所在的网卡没有启用返回FALSE

                int sourceIpInt = inet_addr(sourceIpStr);
                int destIpInt = inet_addr(destIpStr);

                long macinfo = new long();
                int len = 6;
                int res = SendARP(destIpInt, sourceIpInt, ref macinfo, ref len);
                string macStr = Convert.ToString(macinfo, 16);

                return GetRealMac(macStr).ToUpper();
            }
            catch//出现异常返回null
            {
                return null;
            }
        }

        /// <summary>
        /// 转换MAC地址为正常显示的MAC
        /// </summary>
        /// <param name="macSource"></param>
        /// <returns></returns>
        private static string GetRealMac(string macSource)
        {
            string realMac = null;

            if (string.IsNullOrEmpty(macSource)) return null;
            if (macSource.Length < 12) macSource = macSource.PadLeft(12, '0');
            //将MAC地址转换回来
            for (int i = 5; i >= 0; i--)
            {
                realMac += macSource.Substring(i * 2, 2);
            }

            return realMac.ToUpper();
        }
        /// <summary>
        /// 获取IP所在的网卡是否正常工作中
        /// 在18年1月10日前改造成ICMP的PING命令
        /// </summary>
        /// <param name="ipAddress"></param>
        /// <returns></returns>
        public static bool IsIpEnabled(string ipAddress)
        {
            try
            {
                ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
                ManagementObjectCollection moc = mc.GetInstances();

                bool enable = false;
                foreach (ManagementObject mo in moc)
                {
                    if ((bool)mo["IPEnabled"] == true)
                    {
                        var count = (from ip in (string[])mo["IPAddress"]
                                     where ip.Contains(ipAddress)
                                     select ip
                                   ).Count();

                        if (count >= 1)
                        {
                            enable = (bool)mo["IPEnabled"];
                            break;
                        }
                    }
                }
                return enable;
            }
            catch
            {
                return false;
            }
        }
    }
}
